package com.agileai.bpm.bizmoduler.define;

import java.util.ArrayList;
import java.util.List;

import com.agileai.bpm.common.GraphBuilder;
import com.agileai.bpm.common.ProcessDefineHelper;
import com.agileai.bpm.domain.define.Activity.ActTypes;
import com.agileai.bpm.model.ActivitiesDocument.Activities;
import com.agileai.bpm.model.EndActivityType;
import com.agileai.bpm.model.ManualActivityType;
import com.agileai.bpm.model.ProcessDefineDocument;
import com.agileai.bpm.model.ProcessDefineDocument.ProcessDefine;
import com.agileai.bpm.model.StartActivityType;
import com.agileai.bpm.model.TransitionType;
import com.agileai.bpm.model.TransitionsDocument.Transitions;
import com.agileai.bpm.service.running.ProcessHandle;
import com.agileai.common.KeyGenerator;
import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.bizmoduler.core.StandardServiceImpl;
import com.agileai.util.StringUtil;

public class WfProcessManageImpl extends StandardServiceImpl 
	implements WfProcessManage {
	
	public WfProcessManageImpl(){
		super();
	}
	
	public void createRecord(DataParam param) {
		String statementId = sqlNameSpace+"."+"insertRecord";
		processDataType(param, tableName);
		
		String processId = KeyGenerator.instance().genKey();
		String processCode = param.get("WFP_CODE");
		String processName = param.get("WFP_NAME");
		
		ProcessDefineHelper processDefineHelper = new ProcessDefineHelper();
		ProcessDefineDocument defineDocument = processDefineHelper.createProcessDefine(processId,processCode,processName);
		ProcessDefine processDefine = defineDocument.getProcessDefine();
		
		GraphBuilder builder = new GraphBuilder();
		param.put("WFP_GRAPH",builder.createDefaultJsonData(processDefine));
		param.put("WFP_ID",processId);
		param.put("WFP_DEFINE",defineDocument.toString());
		this.daoHelper.insertRecord(statementId, param);
		
		statementId = "wfactivity.insertRecord";
		List<DataParam> activityParamList = new ArrayList<DataParam>();
		this.buildActivityParamList(processDefine, activityParamList);
		this.daoHelper.batchInsert(statementId, activityParamList);
		
		statementId = "wftransition.insertRecord";
		List<DataParam> transitionParamList = new ArrayList<DataParam>();
		this.buildTransitionParamList(processDefine, transitionParamList);
		this.daoHelper.batchInsert(statementId, transitionParamList);
	}
	
	public void updatePorcessDefine(String processId,String processXML,String processJSON) {
		DataParam param = new DataParam("WFP_ID",processId);
		DataRow dataRow = this.getRecord(param);
		DataParam newParam = dataRow.toDataParam(true);
		newParam.put("WFP_DEFINE",processXML);
		if (!StringUtil.isNullOrEmpty(processJSON)){
			newParam.put("WFP_GRAPH",processJSON);			
		}
		this.updateRecord(newParam);
	}
	
	
	private void buildActivityParamList(ProcessDefine processDefine,List<DataParam> activityParamList){
		Activities activities = processDefine.getActivities();
		String processId = processDefine.getId();
		
		DataParam param1 = new DataParam();
		activityParamList.add(param1);
		
		StartActivityType startActivityType = activities.getStartActivity();
		param1.put("WFA_ID",startActivityType.getId(),"WFP_ID",processId,"WFA_CODE",startActivityType.getCode()
				,"WFA_TYPE",ActTypes.start,"WFA_NAME",startActivityType.getName());

		DataParam param2 = new DataParam();
		activityParamList.add(param2);
		ManualActivityType manualActivityType = activities.getManualActivityArray(0);
		param2.put("WFA_ID",manualActivityType.getId(),"WFP_ID",processId,"WFA_CODE",manualActivityType.getCode()
				,"WFA_TYPE",ActTypes.manual,"WFA_NAME",manualActivityType.getName());
		
		DataParam param3 = new DataParam();
		activityParamList.add(param3);
		EndActivityType endActivityType = activities.getEndActivity();
		param3.put("WFA_ID",endActivityType.getId(),"WFP_ID",processId,"WFA_CODE",endActivityType.getCode()
				,"WFA_TYPE",ActTypes.start,"WFA_NAME",endActivityType.getName());
	}
	
	private void buildTransitionParamList(ProcessDefine processDefine,List<DataParam> transitionParamList){
		String processId = processDefine.getId();
		Transitions transitions = processDefine.getTransitions();
		TransitionType[] transitionTypes = transitions.getTransitionArray();
		for (int i = 0;i < transitionTypes.length;i++){
			TransitionType transitionType = transitionTypes[i];
			DataParam param = new DataParam();
			transitionParamList.add(param);
			param.put("WFT_ID",transitionType.getId(),"WFA_SID",transitionType.getFrom(),"WFA_EID",transitionType.getTo(),"WFP_ID",processId
					,"WFT_CODE",transitionType.getCode(),"WFT_NAME",transitionType.getName());
		}
	}

	@Override
	public void createActivity(String processId, String activityId,
			String activityCode, String activityType) {
		DataParam param = new DataParam();
		param.put("WFA_ID",activityId,"WFP_ID",processId,"WFA_CODE",activityCode,"WFA_TYPE",activityType);
		String statementId = "wfactivity.insertRecord";
		this.daoHelper.insertRecord(statementId, param);
	}

	@Override
	public void createTransition(String processId, String transitionId,String transitionCode,
			String fromId, String toId) {
		DataParam param = new DataParam();
		param.put("WFT_ID",transitionId,"WFT_CODE",transitionCode,"WFA_SID",fromId,"WFA_EID",toId,"WFP_ID",processId);
		String statementId = "wftransition.insertRecord";
		this.daoHelper.insertRecord(statementId, param);
	}

	@Override
	public void deleteActivity(String processId, String activityId,List<String> transitionIds) {
		String statementId = "wfactivity.deleteRecord";
		DataParam param = new DataParam();
		param.put("WFA_ID",activityId,"WFP_ID",processId);
		this.daoHelper.deleteRecords(statementId, param);
		
		if (transitionIds != null && transitionIds.size() > 0){
			statementId = "wftransition.deleteRecord";
			List<DataParam> paramList = new ArrayList<DataParam>();
			for (int i=0;i < transitionIds.size();i++){
				String transitionId = transitionIds.get(i);
				DataParam paramTemp = new DataParam();
				paramList.add(paramTemp);
				paramTemp.put("WFP_ID",processId);
				paramTemp.put("WFT_ID",transitionId);
			}
			this.daoHelper.batchDelete(statementId, paramList);
		}
	}

	@Override
	public void deleteTransition(String processId, String transitionId) {
		String statementId = "wftransition.deleteRecord";
		DataParam param = new DataParam();
		param.put("WFT_ID",transitionId,"WFP_ID",processId);
		this.daoHelper.deleteRecords(statementId, param);
	}

	@Override
	public List<DataRow> findRunningActivityList(String processInstanceId) {
		List<DataRow> result = null;
		String statementId = "wfactivity.findRunningActivityList";
		DataParam param = new DataParam();
		param.put("WFIP_ID",processInstanceId);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> queryDidWorkList(String seqId, String type) {
		List<DataRow> result = null;
		String statementId = "wfprocessinstance.queryDidWorkList";
		DataParam param = new DataParam();
		if (ProcessHandle.UserSeqType.USER_ID.equals(type)){
			param.put("USER_ID",seqId);			
		}else{
			param.put("USER_CODE",seqId);
		}
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> queryDoingWorkList(String seqId, String type) {
		List<DataRow> result = null;
		String statementId = "wfprocessinstance.queryDoingWorkList";
		DataParam param = new DataParam();
		if (ProcessHandle.UserSeqType.USER_ID.equals(type)){
			param.put("USER_ID",seqId);			
		}else{
			param.put("USER_CODE",seqId);
		}
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public DataRow getStrRecord(DataParam queyrParam1) {
		String statementId = sqlNameSpace + "." + "getStrRecord";
		DataRow result = this.daoHelper.getRecord(statementId, queyrParam1);
		return result;
	}

	@Override
	public DataRow getDraftCountRecord(String userCode) {
		DataParam param = new DataParam();
		param.put("userCode",userCode);
		String statementId = sqlNameSpace + "." + "getCountRecord";
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public DataRow getTaskListCountRecord(String userCode) {
		DataParam param = new DataParam();
		param.put("userCode",userCode);
		String statementId = sqlNameSpace + "." + "getTaskListCountRecord";
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public DataRow getDoingTaskListCountRecord(String userCode) {
		DataParam param = new DataParam();
		param.put("userCode",userCode);
		String statementId = sqlNameSpace + "." + "getDoingTaskListCountRecord";
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public DataRow getDidTaskListCountRecord(String userCode) {
		DataParam param = new DataParam();
		param.put("userCode",userCode);
		String statementId = sqlNameSpace + "." + "getDidTaskListCountRecord";
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> queryDoingWorkList(DataParam param) {
		List<DataRow> result = new ArrayList<DataRow>();
		String statementId = "wfprocessinstance.queryDoingWorkList";
		String startTime = param.getString("sdate")+" 00:00:00";
		String endTime = param.getString("edate")+" 23:59:59";
		param.put("sdate", startTime,"edate",endTime);
		String type = param.getString("type");
		String seqId = param.getString("seqId");
		if (ProcessHandle.UserSeqType.USER_ID.equals(type)){
			param.put("USER_ID",seqId);			
		}else{
			param.put("USER_CODE",seqId);
		}
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> queryDidWorkList(DataParam param) {
		List<DataRow> result = new ArrayList<DataRow>();
		String statementId = "wfprocessinstance.queryDidWorkList";
		String startTime = param.getString("sdate")+" 00:00:00";
		String endTime = param.getString("edate")+" 23:59:59";
		param.put("sdate", startTime,"edate",endTime);
		String type = param.getString("type");
		String seqId = param.getString("seqId");
		if (ProcessHandle.UserSeqType.USER_ID.equals(type)){
			param.put("USER_ID",seqId);			
		}else{
			param.put("USER_CODE",seqId);
		}
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}
	
	@Override
	public List<DataRow> findFlowInfoRecords() {
		List<DataRow> result = new ArrayList<DataRow>();
		String statementId = "wfprocessinstance.findFlowInfoRecords";
		result = this.daoHelper.queryRecords(statementId, new DataParam());
		return result;
	}
}
